package org.libarae.communication.response;

import java.io.ByteArrayOutputStream;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.libarae.communication.HTTPUtils;
import org.libarae.communication.XmlParseException;
import org.libarae.communication.common.Book;
import org.libarae.communication.common.Type;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;


public class FeaturedTabResponse extends Response{	
	private Vector<Book> mRecentBooks = new Vector<Book>();
	private Vector<Book> mActiveBooks = new Vector<Book>();
	private int mStatNumBooks, mStatBlah; //TODO needs to be decided
	
	public FeaturedTabResponse(int status){
		super(Type.FEATRUED_TAB, status);		
	}
	
	public FeaturedTabResponse(int status, Vector<Book> recentBooks, Vector<Book> activeBooks){
		super(Type.FEATRUED_TAB, status);
		setRecentBooks(recentBooks);
		setActiveBooks(activeBooks);
	}
	
	public FeaturedTabResponse(int status, Vector<Book> recentBooks, Vector<Book> activeBooks, int statNumBooks){
		super(Type.FEATRUED_TAB, status);	
		this.mRecentBooks = recentBooks;
		this.mActiveBooks = activeBooks;
		this.mStatNumBooks = statNumBooks;
	}
	
	
	@Override
	public String createXML() throws XmlParseException {
		Document doc;
		try{
			//setup the factory to build the xml
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
			doc = documentBuilder.newDocument();
		}
		catch (Exception e) {
			throw new XmlParseException("Error creating XML Builder",e);
		}
		
		//create the xml
		Element rootElement = doc.createElement("type");
		rootElement.setAttribute("typeID", super.getType()+"");
		doc.appendChild(rootElement);
		//user name
		Element node = doc.createElement("mStatus");
		node.setTextContent(getStatus()+"");
		rootElement.appendChild(node);

		//put vector in to the xml
		node = doc.createElement("mRecentBooks");
		for(Book b : mRecentBooks){
			Element subNode =  doc.createElement("Book");
			b.setPicture(null);
			b.createXml(doc, subNode);
			node.appendChild(subNode);
		}	
		rootElement.appendChild(node);
		
		node = doc.createElement("mActiveBooks");
		for(Book b : mActiveBooks){
			Element subNode =  doc.createElement("Book");
			b.setPicture(null);
			b.createXml(doc, subNode);
			node.appendChild(subNode);
		}	
		rootElement.appendChild(node);
		
		node = doc.createElement("mStatNumBooks");
		node.setTextContent(mStatNumBooks+"");
		rootElement.appendChild(node);
		
		node = doc.createElement("mStatBlah");
		node.setTextContent(mStatBlah+"");
		rootElement.appendChild(node);
		
		//export the xml to a string
		String output = null;
		try {
			ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(byteArrayOutput);
			transformer.transform(source, result);
			output = byteArrayOutput.toString();
		}
		catch (Exception e) {
			throw new XmlParseException("Error outputting XML to string", e);
		}
		
		//return the string
		return output;
	}

	@Override
	public void decodeXML(Document document) {
		// get the document root and node list
		Element root = document.getDocumentElement();
		NodeList nodeList = root.getChildNodes();

		// set all of the nodes in their proper places
		for (int i = 0; i < nodeList.getLength(); i++) {
			// find what node we have
			String nodeName = nodeList.item(i).getNodeName();
			if (nodeName.equals("mStatus")) {
				setStatus(Integer.parseInt(nodeList.item(i).getTextContent()));
			}
			else if (nodeName.equals("mRecentBooks")) {
				NodeList nodeVector = nodeList.item(i).getChildNodes();
				mRecentBooks = new Vector<Book>();
				for(int p = 0; p < nodeVector.getLength(); p++){
					Book book = new Book();
					book.decodeXML(nodeVector.item(p));					
					mRecentBooks.add(book);
				}
			}
			else if (nodeName.equals("mActiveBooks")) {
				NodeList nodeVector = nodeList.item(i).getChildNodes();
				mActiveBooks = new Vector<Book>();
				for(int p = 0; p < nodeVector.getLength(); p++){
					Book book = new Book();
					book.decodeXML(nodeVector.item(p));					
					mActiveBooks.add(book);
				}
			}
			else if (nodeName.equals("mStatNumBooks")) {
				mStatNumBooks = Integer.parseInt(nodeList.item(i).getTextContent());
			}
			else if (nodeName.equals("mStatBlah")) {
				mStatBlah = Integer.parseInt(nodeList.item(i).getTextContent());
			}
			else {
				System.err.println("Unknow field in object XML: " + nodeName);
			}
		}	
	}


	/**
	 * @return the mRecentBooks
	 */
	public Vector<Book> getRecentBooks() {
		return mRecentBooks;
	}


	/**
	 * @param mRecentBooks the mRecentBooks to set
	 */
	public void setRecentBooks(Vector<Book> mRecentBooks) {
		if(mRecentBooks == null)
			mRecentBooks = new Vector<Book>();
		else
			this.mRecentBooks = mRecentBooks;
	}


	/**
	 * @return the mActiveBooks
	 */
	public Vector<Book> getActiveBooks() {
		return mActiveBooks;
	}


	/**
	 * @param mActiveBooks the mActiveBooks to set
	 */
	public void setActiveBooks(Vector<Book> mActiveBooks) {
		if(mActiveBooks == null)
			this.mActiveBooks = new Vector<Book>();
		else
			this.mActiveBooks = mActiveBooks;
	}


	/**
	 * @return the mStatNumBooks
	 */
	public int getStatNumBooks() {
		return mStatNumBooks;
	}


	/**
	 * @param mStatNumBooks the mStatNumBooks to set
	 */
	public void setStatNumBooks(int mStatNumBooks) {
		this.mStatNumBooks = mStatNumBooks;
	}


	/**
	 * @return the mStatBlah
	 */
	public int getStatBlah() {
		return mStatBlah;
	}


	/**
	 * @param mStatBlah the mStatBlah to set
	 */
	public void setStatBlah(int mStatBlah) {
		this.mStatBlah = mStatBlah;
	}

	@Override
	public String createHTML() {

		StringBuilder sb = new StringBuilder();
		sb.append("<div class=\"holder\">");		
		sb.append("<div style=\"font-size:20px;border-bottom-width:1px;padding-top:8px;border-bottom-style:solid;border-bottom-color: #999;\"><strong>Active:</strong></div>");
		for( Book b : getActiveBooks())
		{//Create a new row for each book result
			sb.append("\n<div class=\"bookHolder\"  onclick=\"location.href='/bookInfo.html?mBid=" + HTTPUtils.encodeURL("" + b.getBID()) + "';\">");
			String title = b.getTitle();
			if(title.length() > 20)
				title = (title.substring(0,20)+"..");
			sb.append("<i>").append(title).append("</i>"); 
			String author = b.getAuthor();
			if(author.length() > 12)
				author = (author.substring(0,12)+"..");
			sb.append(", by <b>").append(author).append("</b>");
			if(b.getISBN() != null && b.getISBN().length() > 0)
				sb.append("<br/>ISBN: ").append(b.getISBN());
			sb.append("<div style=\"float:right;\"><a class=\"nounderline\" href=\"/bookInfo.html?mBid=" + HTTPUtils.encodeURL("" + b.getBID()) +  "\" > Details </a></div>");
			sb.append("</div>");
		}
		
		sb.append("<br/><br/><div style=\"font-size:20px;border-bottom-width: 1px;border-bottom-style:solid;border-bottom-color: #999;\"><strong>Recent:</strong></div>");

		for( Book b : getRecentBooks())
		{//Create a new row for each book result
			sb.append("\n<div class=\"bookHolder\"  onclick=\"location.href='/bookInfo.html?mBid=" + HTTPUtils.encodeURL("" + b.getBID()) + "';\">");
			String title = b.getTitle();
			if(title.length() > 20)
				title = (title.substring(0,20)+"..");
			sb.append("<i>").append(title).append("</i>"); 
			String author = b.getAuthor();
			if(author.length() > 12)
				author = (author.substring(0,12)+"..");
			sb.append(", by <b>").append(author).append("</b>");
			if(b.getISBN() != null && b.getISBN().length() > 0)
				sb.append("<br/>ISBN: ").append(b.getISBN());
			sb.append("<div style=\"float:right;\"><a class=\"nounderline\" href=\"/bookInfo.html?mBid=" + HTTPUtils.encodeURL("" + b.getBID()) +  "\" > Details </a></div>");
			sb.append("</div>");
		}
		sb.append("</div></body>");		
		return HTTPUtils.HTMLPageHeader("") + sb;
	}
}